package com.bkhc.common.permissions.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bkhc.common.annotation.ApiOperation;
import com.bkhc.common.constant.RdisKeyContant;
import com.bkhc.common.entity.ApiInfo;
import com.bkhc.common.permissions.bean.UserPermission;
import com.bkhc.common.service.ApiInfoService;
import com.bkhc.common.service.UserService;
import com.bkhc.common.util.CommonUtil;
import com.bkhc.common.util.response.ResultCode;
import com.bkhc.common.util.response.ResultJson;
import com.bkhc.common.vo.UserBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;



public class SsoFilter implements Filter {

    public String appName;

    private String[] exclusions;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        String exclusionsString = filterConfig.getInitParameter("exclusions");
        appName = filterConfig.getInitParameter("appName");
        if(!StringUtils.isEmpty(exclusionsString)){
            exclusions = exclusionsString.split(",");
        }
    }

    @Override
    public void doFilter(ServletRequest var1, ServletResponse var2, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) var1;
        HttpServletResponse response = (HttpServletResponse) var2;
        boolean flag = true;
        for(String path:exclusions){
            if(request.getRequestURI().contains(path)){
                flag = false;
            }
        }
        if(flag){
            WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(request.getServletContext());
            RequestMappingHandlerMapping mapping = context.getBean(RequestMappingHandlerMapping.class);
            ApiInfoService apiInfoService = context.getBean(ApiInfoService.class);
            HandlerExecutionChain hanler = null;
            try {
                hanler = mapping.getHandler(request);
            } catch (Exception e) {
                e.printStackTrace();
            }
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            PrintWriter pw = null;
            if (hanler == null) {
                //取不到操作项继续往下处理
                filterChain.doFilter(request, response);
            } else {
                HandlerMethod handlerMethod = (HandlerMethod) hanler.getHandler();
                ApiOperation apiOpreation = handlerMethod.getMethod().getAnnotation(ApiOperation.class);
                if(apiOpreation==null){
                    filterChain.doFilter(request, response);
                }else{
                    ApiInfo apiinfo = apiInfoService.getApiByCode(apiOpreation.code());
                    String type = apiOpreation.type();
                    //公共服务不用处理
                    if ("common".equals(apiinfo.getApiType())) {
                        filterChain.doFilter(request, response);
                    } else {
                        UserBean user = CommonUtil.getCrruentUser();
                        if (user == null) {
                            ResultJson resultJson = ResultJson.failure(ResultCode.NO_LOGIN);
                            String res = JSON.toJSONString(resultJson);
                            pw = response.getWriter();
                            pw.append(res);
                            pw.flush();
                        } else {
                            UserPermission permission = (UserPermission) request.getSession(false).getAttribute(RdisKeyContant.USER_PERMISSION_SESSION + "_" + appName);
                            if (permission == null) {
                                UserService userService = context.getBean(UserService.class);
                                permission = userService.queryUserPermission(user.getUserId());
                                if (permission == null) {
                                    ResultJson resultJson = ResultJson.failure(ResultCode.NO_AUTH);
                                    String res = JSON.toJSONString(resultJson);
                                    pw = response.getWriter();
                                    pw.append(res);
                                } else {
                                    request.getSession(false).setAttribute(RdisKeyContant.USER_PERMISSION_SESSION + "_" + appName, permission);
                                    filterChain.doFilter(request, response);
                                }
                            } else {
                                filterChain.doFilter(request, response);
                            }
                        }


                    }
                }
            }
        }else {
            filterChain.doFilter(request, response);
        }

    }
}
